#version 150 core

//
// 鱼眼镜头图像部署的平面
//

// 屏幕的晶格间距
uniform vec2 gap;

// 大小和屏幕的中心位置
uniform vec4 screen;

// 屏幕焦距
uniform float focal;

// 变换矩阵用于旋转屏幕
uniform mat4 rotation;

// 半径和//背景纹理的中心位置
uniform vec4 circle;

// 背景纹理
uniform sampler2D image;

// 背景纹理的尺寸
vec2 size = textureSize(image, 0);

// 规模的背景纹理的质感空间
vec2 scale = vec2(0.5 * size.y / size.x, -0.5) / circle.st;

// 纹理的上//背景纹理的空间的中心位置
vec2 center = circle.pq + 0.5;

// 纹理坐标
out vec2 texcoord;

void main(void)
{
  // 頂点位置
  //   各頂点において gl_VertexID が 0, 1, 2, 3, ... のように割り当てられるから、
  //     x = gl_VertexID >> 1      = 0, 0, 1, 1, 2, 2, 3, 3, ...
  //     y = 1 - (gl_VertexID & 1) = 1, 0, 1, 0, 1, 0, 1, 0, ...
  //   のように GL_TRIANGLE_STRIP 向けの頂点座標値が得られる。
  //   y に gl_InstaceID を足せば glDrawArrayInstanced() のインスタンスごとに y が変化する。
  //   これに格子の間隔 gap をかけて 1 を引けば縦横 [-1, 1] の範囲の点群 position が得られる。
  int x = gl_VertexID >> 1;
  int y = gl_InstanceID + 1 - (gl_VertexID & 1);
  vec2 position = vec2(x, y) * gap - 1.0;

  // 頂点位置をそのままラスタライザに送ればクリッピング空間全面に描く
  ////绘制剪裁空间完全如果您发送//顶点位置，因为它是光栅
  gl_Position = vec4(position, 0.0, 1.0);

  // 視線ベクトル
  //   position にスクリーンの大きさ screen.st をかけて中心位置 screen.pq を足せば、
  //   スクリーン上の点の位置 p が得られるから、原点にある視点からこの点に向かう視線は、
  //   焦点距離 focal を Z 座標に用いて (p, -focal) となる。
  //   これを回転したあと正規化して、その方向の視線単位ベクトルを得る。

  //线的视线矢量
  //如果你自己明白了//屏幕尺寸screen.st中心位置screen.pq过的位置，
  //由于获得在屏幕上的点的位置p，视线朝向从该视点的点原点的线，所述
  //使用焦距焦点的Z坐标成为（P，-focal）。
  //和正火旋转之后它获得视线单位矢量的其方向。
  vec2 p = position * screen.st + screen.pq;
  vec4 vector = normalize(rotation * vec4(p, -focal, 0.0));

  //纹理坐标
  texcoord = acos(-vector.z) * normalize(vector.xy) * scale + center;
}
